package netty.webSocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @Description TODO
 * @Author 李龙平
 * @Date 2020/10/13 14:59
 */
public class MyServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boss, work).channel(NioServerSocketChannel.class)
                    //添加日志
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            //因为是基于http的  使用http的编码器 解码器
                            pipeline.addLast(new HttpServerCodec());
                            //是以块的方式写 添加 chunkedWriteHandler处理器
                            pipeline.addLast(new ChunkedWriteHandler());
                            /*
                                说明
                                http数据传输是多段发送的 HttpObjectAggregator 就可以将多个段聚合
                                这就是威慑呢么数据量过大 会出现多次http请求
                             */
                            pipeline.addLast(new HttpObjectAggregator(8192));
                            /*
                                对于 websocket 他的数据是以帧传输的
                                WebSocketFrame 下面有6个子类
                                浏览器请求时 ws://localhost:7000/xx.do
                                WebSocketServerProtocolHandler 是将http协议转为 ws协议 保持长连接
                             */
                            pipeline.addLast(new WebSocketServerProtocolHandler("/xx.do"));
                            //自定义handler 处理业务逻辑
                            pipeline.addLast(new MyServerHandler());
                        }
                    });
            ChannelFuture channelFuture = bootstrap.bind(6668).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
}
